package cc.owoo.godpen.network.http;

import cc.owoo.godpen.analysis.json.Json;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * HTTP响应
 * Created by nimensei
 * 2022-02-24 下午 06:05
 **/
public class Response extends AbstractContent implements MessageRead, MessageWrite {
    public cc.owoo.godpen.network.http.HttpClient requestClient;// 请求端
    public cc.owoo.godpen.network.http.RequestInfo requestInfo;// 请求信息

    String version = "HTTP/1.1";// 协议版本
    int code = -1;// 返回码
    String message;// 返回消息

    public long requestStartTime;// 请求开始时间戳
    public long responseEndTime;// 响应结束时间戳

    public Response() {
    }

    public Response(HttpClient client, RequestInfo info) {
        this.requestClient = client;
        this.requestInfo = info;
    }

    @Override
    public void read(InputStream input) throws IOException {
        cc.owoo.godpen.network.http.HttpAnalysis.read(input, this, this);
    }

    @Override
    public void analysisAgreement(String string) {
        String[] array = string.split(" ");
        if (array.length < 2)
            return;
        setVersion(array[0]);
        setCode(Integer.parseInt(array[1]));
        if (array.length > 3)
            setMessage(array[2]);
        else
            setMessage(null);
    }

    @Override
    public void write(OutputStream output) throws IOException {
        HttpAnalysis.write(output, this, this);
    }

    @Override
    public String stringifyAgreement() {
        String message = getMessage();
        if (message == null)
            message = "";
        return getVersion() + ' ' +
                getCode() + ' ' + message;
    }

    /**
     * 获取协议版本号
     *
     * @return 协议版本号
     */
    public String getVersion() {
        return version == null ? "HTTP/1.1" : version;
    }

    /**
     * 设置协议版本号
     *
     * @param version 协议版本号
     */
    public void setVersion(String version) {
        this.version = version;
    }

    /**
     * 获取状态码
     *
     * @return 状态码
     */
    public int getCode() {
        return code;
    }

    /**
     * 设置状态码
     *
     * @param code 状态码
     */
    public void setCode(int code) {
        this.code = code;
    }

    /**
     * 获取状态信息
     *
     * @return 状态信息
     */
    public String getMessage() {
        return message;
    }

    @Override
    public int setHeader(String string) {
        return super.setHeader(string);
    }

    @Override
    public boolean setHeader(String key, String value) {
        return super.setHeader(key, value);
    }

    @Override
    public void setContent(Json json) {
        super.setContent(json);
    }

    @Override
    public void setContent(byte[] content) {
        super.setContent(content);
    }

    @Override
    public boolean setContent(File file) {
        return super.setContent(file);
    }

    /**
     * 设置状态信息
     *
     * @param message 状态信息
     */
    public void setMessage(String message) {
        this.message = message;
    }

    /**
     * 获取开始请求的时间戳
     *
     * @return 开始请求的时间戳
     */
    public long getRequestStartTime() {
        return requestStartTime;
    }

    /**
     * 设置开始请求的时间戳
     *
     * @param requestStartTime 开始请求的时间戳
     */
    public void setRequestStartTime(long requestStartTime) {
        this.requestStartTime = requestStartTime;
    }

    /**
     * 获取响应结束的时间戳
     *
     * @return 响应结束的时间戳
     */
    public long getResponseEndTime() {
        return responseEndTime;
    }

    /**
     * 设置响应结束的时间戳
     *
     * @param responseEndTime 响应结束的时间戳
     */
    public void setResponseEndTime(long responseEndTime) {
        this.responseEndTime = responseEndTime;
    }


    /**
     * 响应信息，这个函数一般用来打印到控制台，他比toString更简洁，只输出响应报文的内容
     *
     * @return 响应信息
     */
    public String responseInfo() {
        StringBuilder string = new StringBuilder();
        string.append("[agreement header]").append('\n');
        string.append("version:").append(version).append('\n');
        string.append("code:").append(code).append('\n');
        string.append("message:").append(message).append('\n');
        string.append("[response header]").append('\n');
        stringifyHeader(string);
        string.append("[data]").append('\n');
        HttpUtil.stringifyContent(string, content, this);
        return string.toString();
    }

    @Override
    public String toString() {
        StringBuilder string = new StringBuilder();
        if (requestInfo != null) {
            string.append("[常规]").append('\n');
            string.append("请求URL: ").append(requestInfo.getUrl()).append('\n');
            string.append("请求方法: ").append(requestInfo.method).append('\n');
            string.append("状态代码: ").append(code);
            if (message != null)
                string.append(' ').append(message);
            string.append('\n');
            string.append("远程地址: ").append(requestInfo.getAddressPort()).append('\n');
            string.append("请求耗时: ").append(responseEndTime - requestStartTime).append("ms").append('\n');
            string.append("[请求头]").append('\n');
            HttpUtil.stringifyHeader(string, requestInfo);
            string.append("[请求数据]").append('\n');
            HttpUtil.stringifyContent(string, requestInfo.content, requestInfo);
            string.append('\n');
        }
        string.append("[响应头]").append('\n');
        HttpUtil.stringifyHeader(string, this);
        string.append("[响应数据]").append('\n');
        HttpUtil.stringifyContent(string, content, this);
        string.append('\n');
        return string.toString();
    }
}
